package com.glkj.vipsystem.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.glkj.vipsystem.common.exception.BizException;
import com.glkj.vipsystem.common.utils.Constant;
import com.glkj.vipsystem.entity.ao.VipCardAO;
import com.glkj.vipsystem.entity.ao.VipCardRecordAO;
import com.glkj.vipsystem.entity.gen.VipCardCancelRecord;
import com.glkj.vipsystem.mapper.VipCardMapper;
import com.glkj.vipsystem.service.IVipCardCancelRecordService;
import com.glkj.vipsystem.service.IVipCardRecordService;
import com.glkj.vipsystem.service.IVipCardService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * VipCard 服务实现类
 * </p>
 *
 * @author Limuchan
 * @since 2019-09-07 11:38:56
 */
@Service
public class VipCardService extends ServiceImpl<VipCardMapper, VipCardAO> implements IVipCardService {

    @Resource
    private IVipCardRecordService vipCardRecordService;
    @Resource
    private IVipCardCancelRecordService vipCardCancelRecordService;

    /**
     * 新开会员卡
     *
     * @param vipCard 会员卡信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void save(VipCardAO vipCard, String operator) {
        vipCard.setOperator(operator);
        // 插入会员卡记录
        this.insert(vipCard);

        // 插入会员卡变更记录
        VipCardRecordAO record = new VipCardRecordAO();
        record.setVipCardId(vipCard.getId())
                .setMemberId(vipCard.getMemberId())
                .setCompanyId(vipCard.getCompanyId())
                .setShopId(vipCard.getShopId())
                .setCardNo(vipCard.getCardNo())
                .setMemberName(vipCard.getMemberName())
                .setMemberMobile(vipCard.getMemberMobile())
                .setCardType(vipCard.getCardType())
                .setChangeType(Constant.VipCardRecordChangeType.NEW.getValue()) // 3-新开
                .setChangeFee(vipCard.getCardFee())
                .setBalanceChange(vipCard.getCardBalance())
                .setTimesChange(vipCard.getCardTimes())
                .setTimesChangeType(vipCard.getCardTimesType())
                .setPointsChange(vipCard.getCardPoints())
                .setCreateTime(new Date())
                .setOperator(operator);
        // 卡类型校验
        Integer cardType = vipCard.getCardType();
        String changeDesc = "";
        if (cardType == Constant.VipCardType.CIKA.getValue()) {
            // 次卡
            changeDesc = "新开次卡";
        } else if (cardType == Constant.VipCardType.CHONGZHIKA.getValue()) {
            // 充值卡
            changeDesc = "新开充值卡";
        } else if (cardType == Constant.VipCardType.JIFENKA.getValue()) {
            // 积分卡
            changeDesc = "新开积分卡";
        }
        record.setChangeDesc(changeDesc);

        vipCardRecordService.insert(record);
    }

    /**
     * 批量新增
     *
     * @param vipCardAOS 会员卡信息
     * @param operator   操作员
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveBatch(List<VipCardAO> vipCardAOS, String operator) {
        if (CollectionUtils.isEmpty(vipCardAOS) || StringUtils.isBlank(operator)) {
            return;
        }
        for (VipCardAO vipCardAO : vipCardAOS) {
            this.save(vipCardAO, operator);
        }
    }

    /**
     * 批量注销会员卡
     *
     * @param vipCardIds 会员卡id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteBatch(List<Integer> vipCardIds, String operator) {
        if (CollectionUtils.isEmpty(vipCardIds)) return;
        List<VipCardAO> vipCardAOS = this.selectList(
                new EntityWrapper<VipCardAO>()
                        .in("id", vipCardIds)
        );
        if (CollectionUtils.isEmpty(vipCardAOS)) return;
        // 添加注销记录
        List<VipCardCancelRecord> cancelRecords =
                vipCardAOS.stream().map(it -> new VipCardCancelRecord(it, operator)).collect(Collectors.toList());
        vipCardCancelRecordService.insertBatch(cancelRecords);
        this.deleteBatchIds(vipCardIds);
    }

    /**
     * 调整会员卡
     *
     * @param vipCard  会员卡信息
     * @param operator 操作员
     */
    @Override
    public void update(VipCardAO vipCard, String operator) {
        VipCardAO selectById = this.selectById(vipCard.getId());
        vipCard.setShopId(selectById.getShopId());
        VipCardRecordAO record = new VipCardRecordAO();
        // 卡类型校验
        String changeDesc = "";
        Integer cardType = selectById.getCardType();
        if (cardType == Constant.VipCardType.CIKA.getValue()) {
            // 次卡
            if (vipCard.getCardTimesType() == 1) {
                record.setTimesChangeType(1);
                // 有效次数卡
                if (vipCard.getCardTimes() == null || vipCard.getCardTimes() <= 0) {
                    throw new BizException("请输入要增加的次数");
                } else {
                    selectById.setCardTimes(selectById.getCardTimes() + vipCard.getCardTimes());
                    record.setTimesChange(vipCard.getCardTimes());
                }
                changeDesc = "增加次数";
                if (selectById.getCardTimesType() == 0) {
                    // 不限次变更为有限次
                    record.setTimesChange(vipCard.getCardTimes());
                    selectById.setCardTimes(vipCard.getCardTimes());
                    changeDesc = "不限次数卡变更为有限次数卡";
                }
            } else if (vipCard.getCardTimesType() == 0) {
                if (selectById.getCardTimesType() == 1) {
                    changeDesc = "有限次数卡变更为不限次数卡";
                    record.setTimesChange(0);
                    selectById.setCardTimes(0);
                }
                record.setTimesChangeType(0);
            }
            if (vipCard.getExpireTime() == null || vipCard.getExpireTime().before(new Date())
                    || vipCard.getExpireTime().before(selectById.getExpireTime())) {
                throw new BizException("请选择正确的有效期");
            }
            if (vipCard.getExpireTime().after(selectById.getExpireTime())) {
                record.setExpireTimeChange("原有效期" + DateUtil.format(selectById.getExpireTime(), "yyyy-MM-dd")
                        + "变更至现有效期" + DateUtil.format(vipCard.getExpireTime(), "yyyy-MM-dd"));
                if (StringUtils.isNotBlank(changeDesc)) {
                    changeDesc += ",调整有效期";
                } else {
                    changeDesc = "调整有效期";
                }
            }
            selectById.setCardTimesType(vipCard.getCardTimesType());
            selectById.setExpireTime(vipCard.getExpireTime());
        } else if (cardType == Constant.VipCardType.CHONGZHIKA.getValue()) {
            // 充值卡
            if (vipCard.getCardBalance() == null ||
                    vipCard.getCardBalance().compareTo(new BigDecimal("0")) <= 0) {
                throw new BizException("请正确输入要充值的金额");
            }
            selectById.setCardBalance(vipCard.getCardBalance().add(selectById.getCardBalance()));
            record.setBalanceChange(vipCard.getCardBalance());
            changeDesc = "充值金额";
        } else {
            // 只有次卡和充值卡可调整 错误
            throw new BizException("只有次卡和充值卡可调整");
        }
        this.updateById(selectById);
        // 插入会员卡变更记录
        record.setVipCardId(selectById.getId())
                .setMemberId(selectById.getMemberId())
                .setCompanyId(selectById.getCompanyId())
                .setShopId(vipCard.getShopId())
                .setCardNo(selectById.getCardNo())
                .setMemberName(selectById.getMemberName())
                .setMemberMobile(selectById.getMemberMobile())
                .setCardType(selectById.getCardType())
                .setChangeType(Constant.VipCardRecordChangeType.SYSTEM.getValue()) // 1-后台调整
                .setChangeFee(vipCard.getCardFee())
                .setCreateTime(new Date())
                .setOperator(operator);
        record.setChangeDesc(changeDesc);

        vipCardRecordService.insert(record);
    }

    /**
     * 会员卡消费
     *
     * @param cardId        会员卡id
     * @param shopId        消费店铺
     * @param balanceAmount 余额消费金额
     * @param costPoints    消费的积分
     * @param givePoints    赠送的积分
     * @param times         消费次数
     * @param operator      收银员
     */
    @Override
    public void cost(Integer cardId, Integer shopId, BigDecimal balanceAmount, Integer costPoints, Integer givePoints, Integer times, String operator) {
        if (cardId == null || shopId == null) {
            return;
        }

        VipCardAO selectById = this.selectById(cardId);
        VipCardRecordAO record = new VipCardRecordAO();
        Integer cardType = selectById.getCardType();
        record.setVipCardId(selectById.getId())
                .setShopId(shopId)
                .setMemberId(selectById.getMemberId())
                .setCompanyId(selectById.getCompanyId())
                .setCardNo(selectById.getCardNo())
                .setMemberName(selectById.getMemberName())
                .setMemberMobile(selectById.getMemberMobile())
                .setCardType(selectById.getCardType())
                .setChangeType(Constant.VipCardRecordChangeType.COST.getValue()) // 2-消费
                .setCreateTime(new Date())
                .setOperator(operator);

        // 消费
        // 修改会员卡信息
        if (cardType == Constant.VipCardType.CHONGZHIKA.getValue()) {
            // 充值卡
            selectById.setCardBalance(selectById.getCardBalance().subtract(balanceAmount));
            record.setChangeDesc("消费花费余额");
            if (balanceAmount.compareTo(new BigDecimal("0")) > 0) {
                record.setBalanceChange(new BigDecimal("-" + balanceAmount.toPlainString()));
                vipCardRecordService.insert(record);
            }
        } else if (cardType == Constant.VipCardType.JIFENKA.getValue()) {
            // 积分卡
            selectById.setCardPoints(selectById.getCardPoints() + givePoints - costPoints);
            if (costPoints > 0) {
                record.setChangeDesc("消费消耗积分");
                record.setPointsChange(-costPoints);
                vipCardRecordService.insert(record);
            }
            if (givePoints > 0) {
                record.setChangeDesc("消费赠送积分");
                record.setPointsChange(givePoints);
                vipCardRecordService.insert(record);
            }
        } else if (cardType == Constant.VipCardType.CIKA.getValue()) {
            selectById.setCardTimes(selectById.getCardTimes() - times);
            record.setChangeDesc("消费消耗次数");
            record.setTimesChange(-1);
            vipCardRecordService.insert(record);
        }

        this.updateById(selectById);
    }

}
